package app.blog.entity;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;

import slap.berkeleydb.BDB;
import slap.paradigm.Function;

import app.blog.Blog;

import com.sleepycat.persist.EntityCursor;
import com.sleepycat.persist.PrimaryIndex;
import com.sleepycat.persist.SecondaryIndex;
import com.sleepycat.persist.model.Entity;
import com.sleepycat.persist.model.NotPersistent;
import com.sleepycat.persist.model.PrimaryKey;
import com.sleepycat.persist.model.Relationship;
import com.sleepycat.persist.model.SecondaryKey;


@Entity
public class Article extends Post{
	
	protected static PrimaryIndex<Integer, Article> primaryIndex = 
		BDB.instanse(Blog.bdbName).getEntityStore().getPrimaryIndex(Integer.class, Article.class);
	
	protected static SecondaryIndex<String, Integer, Article> indexOnName = 
		BDB.instanse(Blog.bdbName).getEntityStore().getSecondaryIndex(primaryIndex, String.class, "name");
	
	protected static SecondaryIndex<Date, Integer, Article> indexOnPupDate = 
		BDB.instanse(Blog.bdbName).getEntityStore().getSecondaryIndex(primaryIndex, Date.class, "pubDate");
	
	
	public static void persist(Article post){
		primaryIndex.putNoReturn(post);
	}
	
	public static Article getById(Integer id){
		return primaryIndex.get(id);
	}
	
	public static Article getByName(String name) {
		return indexOnName.get(name);
	}
	
	public static List<Article> all() {
		List<Article> all;
		all = BDB.asList(primaryIndex);
		return all;
	}
	
	public static List<Article> recent(int n) {
		EntityCursor<Article> cu = indexOnPupDate.entities();
		int count = (int) indexOnPupDate.count();
		n = count>n ? n : count;
		Article[] rp = new Article[n];
		Article p;
		for(int i=n-1;i>=0;i--){
			if((p=cu.next()) != null){
				rp[i] = p;
			}else{
				break;
			}
			
		}
		cu.close();
		return Arrays.asList(rp);
	}
	
	public static long count(){
		return primaryIndex.count();
	}
	
	
	public String content;
	
	public List<Category> categories(){
		final List<Category> list = new ArrayList<Category>();
		EntityCursor<PostJoinCategory> cursor = 
			PostJoinCategory.indexOnPostId.subIndex(this.id).entities();
		try{
			for(PostJoinCategory join : cursor){
				list.add(Category.getById(join.category_id));
			}
		}finally{
			cursor.close();
		}
		return list;
	}
	
	public List<Tag> tags(){
		final List<Tag> list = new ArrayList<Tag>();
		EntityCursor<PostJoinTag> cursor = 
			PostJoinTag.indexOnPostId.subIndex(this.id).entities();
		try{
			for(PostJoinTag join : cursor){
				list.add(Tag.getById(join.tag_id));
			}
		}finally{
			cursor.close();
		}
		
		return list;
	}
	
	public void addCategory(Category cat){
		if(this.id == null || cat.id == null){
			throw new IllegalArgumentException("The two oprator must be persist first.");
		}
		PostJoinCategory.persist(new PostJoinCategory(this.id, cat.id));
	}
	
	public void addTag(Tag tag){
		if(this.id == null || tag.id == null){
			throw new IllegalArgumentException("The two oprator must be persist first.");
		}
		PostJoinTag.persist(new PostJoinTag(this.id, tag.id));
	}
	
}
